﻿using ConfigLib;
using KYJBLL;
using KYJControlLib;
using KYJModels;
using KYJScadaProModbusRtu;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Management;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
using thinger.CommunicationLib.Helper;
using thinger.DataConvertLib;

namespace KYJScadaProModbusRTU
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        { 
            InitializeComponent();

            //实例化定时存储定时器
            this.storeTimer = new System.Timers.Timer();
            this.storeTimer.Interval = 1000;
            this.storeTimer.AutoReset = true;
            this.storeTimer.Elapsed += StoreTimer_Elapsed;

            //监控集合发生变化
            actualAlarmList.CollectionChanged += ActualAlarmList_CollectionChanged;

            //窗体关闭前确认
            this.FormClosing += FrmMain_FormClosing;

            this.Load += FrmMain_Load;
        }

        #region  定时存储
        private void StoreTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            this.Invoke(new Action(() =>
            {
                this.lbl_DateTime.Text = CurrentTime + " " + week;
            }));

            if (CommomMethods.connectState && new SQLiteManage().IsTableExits("ActualData"))
            {
                varValueList = new List<string>() { CurrentTime };
                varValueList.AddRange(CommomMethods.plcDevice.StoreVarList.Select(c => c.VarValue?.ToString()).ToList());
                try
                {
                    actualDataManage.AddActualData(varNameList, varValueList);
                }
                catch (Exception ex)
                {
                    CommomMethods.AddLog(true, "实时存储出错：" + ex.Message);
                }
            }
        }
        #endregion

        #region 字段
        //创建配置文件的路径
        string xmlPath = Application.StartupPath + "\\settings\\settings.json";

        //创建委托对象
        private Action<SysLog> AddAlarmDelegate;

        //创建实时报警集合
        private ObservableCollection<string> actualAlarmList = new ObservableCollection<string>();

        //创建一个消息过滤对象
        private MessageFilter messageFilter;

        //定时存储定时器
        private System.Timers.Timer storeTimer;

        //实时数据业务对象
        private ActualDataManage actualDataManage = new ActualDataManage();

        //所有归档变量的名称l集合
        private List<string> varNameList;

        //所有归档变量的值l集合
        private List<string> varValueList;
        #endregion

        // 当前时间
        private string CurrentTime
        {
            get { return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); }
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            //1.设置登录用户
            this.lbl_LoginName.Text = CommomMethods.currentAdmin.LoginName;

            //2.打开日志报警窗体
            OpenWindown(FormName.日志报警);

            //3.打开控制流程窗体
            OpenWindown(FormName.控制流程);

            //4.登录日志
            CommomMethods.AddOPLog(false, "登录成功，登录用户：" + CommomMethods.currentAdmin.LoginName);

            // 自动锁屏
            if (CommomMethods.sysConfig.AutoLock)
            {
                messageFilter = new MessageFilter();
                Application.AddMessageFilter(messageFilter);
            }

            if (CommomMethods.sysConfig != null)
            {
                CommomMethods.AddLog(false, "加载系统配置成功");
            }
            else
            {
                CommomMethods.AddLog(true, "加载系统配置失败");
            }

            //读取变量配置信息
            var result = GetDeviceByPath(xmlPath);

            //读取成功
            if (result.IsSuccess)
            {
                //获取设备对象及设置设备
                CommomMethods.plcDevice = result.Content;
                CommomMethods.plcDevice.PortName = "COM20";

                //设置成长地址模型
                CommomMethods.plcDevice.IsShortAddress = false;

                //设置大小端
                CommomMethods.plcDevice.DataFormat = (int)DataFormat.CDAB;
                CommomMethods.plc.DataFormat = DataFormat.CDAB;

                //初始化
                CommomMethods.plcDevice.Init();

                //初始化varNameList
                varNameList = new List<string>() { "InsertTime" };
                varNameList.AddRange(CommomMethods.plcDevice.StoreVarList.Select(c => c.VarName).ToList());

                //报警触发事件
                CommomMethods.plcDevice.AlarmTriggerEvent += PlcDevice_AlarmTriggerEvent;

                //实例化线程取消源
                CommomMethods.plcDevice.Cts = new CancellationTokenSource();

                //开启线程
                Task.Run(new Action(() =>
                {
                    PlcCommunication(CommomMethods.plcDevice);
                }), CommomMethods.plcDevice.Cts.Token);

                //开启定时器
                this.storeTimer.Start();
            }
            //读取失败
            else
            {
                CommomMethods.AddLog(true, "加载配置文件失败:" + result.Message);
            }
        }

        #region  报警触发事件
        private void PlcDevice_AlarmTriggerEvent(object sender, AlarmEventArgs e)
        {
            AddAlarm(new SysLog()
            {
                InsertTime = CurrentTime,
                LogType = "系统报警",
                Note = e.AlarmNote,
                Operater = CommomMethods.currentAdmin.LoginName,
                VarName = e.Name,
                AlarmSet = e.SetValue,
                AlarmValue = e.CurrentValue,
                AlarmType = e.IsTrigger ? "触发" : "消除"
            });
            //触发报警
            if (e.IsTrigger)
            {
                if (!this.actualAlarmList.Contains(e.AlarmNote))
                {
                    this.actualAlarmList.Add(e.AlarmNote);
                }
            }
            //消除报警
            else
            {
                if (this.actualAlarmList.Contains(e.AlarmNote))
                {
                    this.actualAlarmList.Remove(e.AlarmNote);
                }
            }
        }
        #endregion

        #region 多线程读取数据
        private void PlcCommunication(ModbusRTUDevice device)
        {
            while (!device.Cts.IsCancellationRequested)
            {
                if (device.IsConnected)
                {
                    //读取
                    foreach (var group in device.GroupList)
                    {
                        if (group.IsActive)
                        {
                            var result = GetGroupValue(device,group);

                            //如果读取成功
                            if (result.IsSuccess)
                            {
                                //设置通讯状态
                                SetConnectState(true);

                                //清零错误次数
                                device.ErrorTimes = 0;
                            }
                            else
                            {
                                device.ErrorTimes++;
                                if (device.ErrorTimes >= device.AllowErrorTimes)
                                {
                                    //设置通讯状态
                                    SetConnectState(false);

                                    //这里要注意一下，并不是断线重连
                                    //如果断线了，就不应该重连
                                    //如果不断线，就应该重连
                                    //如何判断是断线还串口没了，通过判断串口是否存在
                                    if (IsComExist(device.PortName))
                                    {
                                        Thread.Sleep(10);
                                        continue;
                                    }
                                    else
                                    {
                                        device.IsConnected = false;

                                        //写日志
                                        CommomMethods.AddLog(true, "通讯读取出错：" + result.Message);

                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    //连接

                    //是否第一次连接,如果不是第一次连接

                    if (device.IsFirstConnect == false)
                    {
                        Thread.Sleep(device.ReConnectTime);
                        CommomMethods.plc?.DisConnect();
                    }

                    //连接plc
                    var result = CommomMethods.plc.Connect(device.PortName, device.BaudRate, device.DataBits, device.Parity, device.StopBits);

                    if (result)
                    {
                        device.IsConnected = true;

                        //设置通讯状态
                        SetConnectState(true);

                        //写入日志
                        CommomMethods.AddLog(false, device.IsFirstConnect? "PLC初次连接成功" : "PLC重新连接成功");
                    }
                    else
                    {
                        device.IsConnected = false;

                        //设置通讯状态
                        SetConnectState(false);

                        //写入日志
                        CommomMethods.AddLog(true, device.IsFirstConnect? "PLC初次连接失败" : "PLC重新连接失败");
                    }

                    //清除某次连接标志位
                    if (device.IsFirstConnect)
                    {
                        device.IsFirstConnect = false;
                    }
                }
            }
        }
        #endregion

        #region 实时报警
        private void AddAlarm(SysLog sysLog)
        {
            if (this.AddAlarmDelegate != null)
            {
                AddAlarmDelegate(sysLog);
            }
        }
        #endregion

        #region 集合改变处理方式
        private void ActualAlarmList_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            //根据集合的数量进行处理
            //如果集合的数量为0，则不显示AlarmPanel
            //如果集合的数量为1，则不显示AlarmPanel.ScrollText设置文本为集合的索引1，同时设置IsScroll为false;
            //如果集合的数量大于1，则不显示AlarmPanel.ScrollText设置文本为集合的所有数据，同时设置IsScroll为true;
            this.Invoke(new Action(() =>
            {
                switch (this.actualAlarmList.Count)
                {
                    case 0:
                        this.AlarmPanel.Visible = false;
                        break;
                    case 1:
                        this.AlarmPanel.Visible = true;
                        this.scrollText1.TextScroll = this.actualAlarmList[0];
                        this.scrollText1.IsScoll = false;
                        break;
                    default:
                        this.AlarmPanel.Visible = true;
                        this.scrollText1.TextScroll = string.Join("   ", this.actualAlarmList);
                        this.scrollText1.IsScoll = true;
                        break;
                }
            }));
        }
        #endregion

        #region 读取单个通讯组的方法
        private OperateResult GetGroupValue(ModbusRTUDevice device, ModbusRTUGroup group)
        {
            //解析起始地址

            //1.40001  1.00001

            //知道哪个存储区  ReadByteArray   ReadBoolArray

            //需要知道起始地址    解析

            var addResult = ModbusHelper.ModbusAddressAnalysis(group.Start, 0, device.IsShortAddress);

            if (addResult.IsSuccess == false) return OperateResult.CreateFailResult(addResult.Message);

            //判断为3区还是4区
            if (addResult.Content1 == thinger.CommunicationLib.StoreArea.ModbusStoreArea.X3 || addResult.Content1 == thinger.CommunicationLib.StoreArea.ModbusStoreArea.X4)
            {
                var result = CommomMethods.plc.ReadByteArray(group.Start, (ushort)group.Length);

                if (result.IsSuccess)
                {
                    //变量解析
                    if (result.Content.Length == group.Length * 2)
                    {
                        //遍历通讯中的每一个变量
                        foreach (var variable in group.VarList)
                        {
                            //解析变量
                            var analysis = AnalysisStartAddress(variable.Start);
                            if (analysis.IsSuccess)
                            {
                                int start = analysis.Content1;
                                int offset = analysis.Content2;  //偏移量或长度

                                start -= addResult.Content3;
                                start *= 2;

                                switch (variable.VarType.ToUpper())
                                {
                                    case "BOOL":
                                        /*variable.VarValue = BitLib.GetBitFrom2BytesArray(result.Content, start, offset,
                                            (DataFormat)device.DataFormat == DataFormat.ABCD || (DataFormat)device.DataFormat == DataFormat.CDAB);*/
                                        variable.VarValue = BitLib.GetBitFrom2BytesArray(result.Content, start,offset,true);
                                        break;
                                    case "BYTE":
                                        /*variable.VarValue = ByteLib.GetByteFromByteArray(result.Content,
                                            (DataFormat)device.DataFormat == DataFormat.ABCD || (DataFormat)device.DataFormat == DataFormat.CDAB ? start : start + 1);*/
                                        variable.VarValue = ByteLib.GetByteFromByteArray(result.Content,start);
                                        break;
                                    case "SHORT":
                                        variable.VarValue = ShortLib.GetShortFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
                                        break;
                                    case "USHORT":
                                        variable.VarValue = UShortLib.GetUShortFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
                                        break;
                                    case "INT":
                                        variable.VarValue = IntLib.GetIntFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
                                        break;
                                    case "UINT":
                                        variable.VarValue = UIntLib.GetUIntFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
                                        break;
                                    case "LONG":
                                        variable.VarValue = LongLib.GetLongFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
                                        break;
                                    case "ULONG":
                                        variable.VarValue = ULongLib.GetULongFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
                                        break;
                                    case "FLOAT":
                                        variable.VarValue = FloatLib.GetFloatFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
                                        break;
                                    case "DOUBLE":
                                        variable.VarValue = DoubleLib.GetDoubleFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
                                        break;
                                    case "STRING":
                                        variable.VarValue = StringLib.GetStringFromByteArrayByEncoding(result.Content, start, offset, Encoding.ASCII);
                                        break;
                                    case "BYTEARRAY":
                                        variable.VarValue = ByteArrayLib.GetByteArrayFromByteArray(result.Content, start, offset);
                                        break;
                                    case "HXESTRING":
                                        variable.VarValue = StringLib.GetHexStringFromByteArray(result.Content, start, offset);
                                        break;
                                    default:
                                        break;
                                }

                                //线性转换
                                var operateResult = MigrationLib.GetMigrationValue(variable.VarValue, variable.Scale.ToString(), variable.Offset.ToString());

                                if (operateResult.IsSuccess)
                                {
                                    variable.VarValue = operateResult.Content;
                                }
                                else
                                {
                                    variable.VarValue = null;
                                    CommomMethods.AddLog(true, "线性转换失败：" + operateResult.Message);
                                }

                                //更新变量
                                device.Update(variable);
                            }
                            else
                            {
                                return OperateResult.CreateFailResult(analysis.Message);
                            }
                        }

                    }
                    else
                    {
                        return OperateResult.CreateFailResult($"读取长度{result.Content.Length}与通讯组长度{group.Length}不一致");
                    }
                }
                else
                {
                    return OperateResult.CreateFailResult(result.Message);
                }
            }

            //判断为0区或1区
            else
            {
                var result = CommomMethods.plc.ReadBoolArray(group.Start, (ushort)group.Length);
                if (result.IsSuccess)
                {
                    //变量解析
                    if (result.Content.Length == group.Length)
                    {
                        //遍历通讯中的每一个变量
                        foreach (var variable in group.VarList)
                        {
                            //解析变量
                            var analysis = AnalysisStartAddress(variable.Start);

                            if (analysis.IsSuccess)
                            {
                                int start = analysis.Content1;
                                start -= addResult.Content3;

                                switch (variable.VarType.ToUpper())
                                {
                                    case "BOOL":
                                        variable.VarValue = result.Content[start];
                                        break;
                                    default:
                                        break;
                                }
                                //更新变量
                                device.Update(variable);
                            }
                            else
                            {
                                return OperateResult.CreateFailResult(analysis.Message);
                            }
                        }
                    }
                    else
                    {
                        return OperateResult.CreateFailResult($"读取长度{result.Content.Length}与通讯组长度{group.Length}不一致");
                    }
                }
                else
                {
                    return OperateResult.CreateFailResult(result.Message);
                }
            }

            return OperateResult.CreateSuccessResult();
        }
        #endregion

        #region 设置连接状态
        private void SetConnectState(bool state)
        {
            if (this.led_State.InvokeRequired)
            {
                this.led_State.Invoke(new Action<bool>(SetConnectState), state);
            }
            else
            {
                CommomMethods.connectState = state;
                this.led_State.State = state;
            }
        }
        #endregion

        #region  判断是断线还串口没了(该方法还没有验证)
        private bool IsComExist(string portName)
        {
            //这方法有BUG
            // SerialPort.GetPortNames().Contains(portName);
            List<string> result = new List<string>();
            try
            {
                //搜索设备管理器中的所有条目
                using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * from Win32_PnPEntity"))
                {
                    var hardInfos = searcher.Get();
                    foreach (var hardInfo in hardInfos)
                    {
                        if (hardInfo.Properties["Name"].Value != null)
                        {
                            string name = hardInfo.Properties["Name"].Value.ToString();
                            if (name.Contains("COM") && name.EndsWith(")"))
                            {
                                if (name.Contains("->"))
                                {
                                    result.Add(name.Substring(name.IndexOf('(') + 1, name.IndexOf(')') - name.IndexOf('-') - 2));
                                }
                                else
                                {
                                    result.Add(name.Substring(name.IndexOf('(') + 1, name.IndexOf(')') - name.IndexOf('(') - 1));
                                }
                            }
                        }
                    }
                    searcher.Dispose();
                }
            }
            catch
            {
                result = new List<string>();
            }
            return result.Contains(portName);
        }
        #endregion

        #region 将配置文件解析成对象
        private OperateResult<ModbusRTUDevice> GetDeviceByPath(string xmlPath)
        {
            List<Project> projects = new ConfigManage().LoadProjects(xmlPath);

            //说明配置了项目
            if (projects != null && projects.Count > 0)
            {
                Project project = projects[0];

                if (project.ModbusRTUList.Count > 0)
                {
                    var device = project.ModbusRTUList[0];

                    if (device.IsActive)
                    {
                        return OperateResult.CreateSuccessResult(device);
                    }
                    else
                    {
                        return OperateResult.CreateFailResult<ModbusRTUDevice>(new OperateResult("请检查是否激活"));
                    }
                }
                else
                {
                    return OperateResult.CreateFailResult<ModbusRTUDevice>(new OperateResult("请检查是否含有ModbusRTU设备"));
                }
            }
            else
            {
                return OperateResult.CreateFailResult<ModbusRTUDevice>(new OperateResult("请检查配置文件是否正确"));
            }
        }
        #endregion

        #region 解析变量的起始地址
        private OperateResult<int, int> AnalysisStartAddress(string start, int fromBase = 10)
        {
            try
            {
                if (start.Contains("."))
                {
                    string[] result = start.Split('.');
                    if (result.Length == 2)
                    {
                        return OperateResult.CreateSuccessResult(Convert.ToInt32(result[0], fromBase), Convert.ToInt32(result[1]));
                    }
                    else
                    {
                        return OperateResult.CreateFailResult<int, int>(new OperateResult("起始地址填写不正确:" + start));
                    }
                }
                else if (start.Contains("|"))
                {
                    string[] result = start.Split('|');
                    if (result.Length == 2)
                    {
                        return OperateResult.CreateSuccessResult(Convert.ToInt32(result[0], fromBase), Convert.ToInt32(result[1]));
                    }
                    else
                    {
                        return OperateResult.CreateFailResult<int, int>(new OperateResult("起始地址填写不正确:" + start));
                    }
                }
                else
                {
                    return OperateResult.CreateSuccessResult(Convert.ToInt32(start, fromBase), 0);
                }

            }
            catch (Exception ex)
            {
                return OperateResult.CreateFailResult<int, int>(new OperateResult($"起始地址{start}转换出错:" + ex.Message));
            }

        }
        #endregion

        #region 导航栏的切换
        private bool naviPanel1_ButtonSelectEvent(object sender, EventArgs e)
        {
            if (sender is FormName formName)
            {
                //权限设置
                switch (formName)
                {
                    case FormName.日志报警:
                        if (!CommomMethods.currentAdmin.LogAlarm)
                        {
                            new FrmMessageBoxWithoutAck("当前登录用户权限不足", "权限不足").ShowDialog();
                            return false;
                        }
                        break;
                    case FormName.日志查询:
                        if (!CommomMethods.currentAdmin.HistoryLog)
                        {
                            new FrmMessageBoxWithoutAck("当前登录用户权限不足", "权限不足").ShowDialog();
                            return false;
                        }
                        break;
                    case FormName.参数设置:
                        if (!CommomMethods.currentAdmin.ParamSet)
                        {
                            new FrmMessageBoxWithoutAck("当前登录用户权限不足", "权限不足").ShowDialog();
                            return false;
                        }
                        break;
                    case FormName.实时趋势:
                        if (!CommomMethods.currentAdmin.ActualTrend)
                        {
                            new FrmMessageBoxWithoutAck("当前登录用户权限不足", "权限不足").ShowDialog();
                            return false;
                        }
                        break;
                    case FormName.历史趋势:
                        if (!CommomMethods.currentAdmin.HistoryTrend)
                        {
                            new FrmMessageBoxWithoutAck("当前登录用户权限不足", "权限不足").ShowDialog();
                            return false;
                        }
                        break;
                    case FormName.数据报表:
                        if (!CommomMethods.currentAdmin.Report)
                        {
                            new FrmMessageBoxWithoutAck("当前登录用户权限不足", "权限不足").ShowDialog();
                            return false;
                        }
                        break;
                    case FormName.用户管理:
                        if (!CommomMethods.currentAdmin.UserManage)
                        {
                            new FrmMessageBoxWithoutAck("当前登录用户权限不足", "权限不足").ShowDialog();
                            return false;
                        }
                        break;
                    case FormName.退出系统:
                        this.Close();
                        return false;
                    default:
                        break;
                }
                //打开窗体
                OpenWindown(formName);
                return true;
            }

            return false;
        }

        /// <summary>
        /// 通用打开窗体
        /// </summary>
        /// <param name="formName"></param>
        private void OpenWindown(FormName formName)
        {
            int total = this.MainPanel.Controls.Count;

            int closeCount = 0;

            bool isFind = false;

            for (int i = 0; i < total; i++)
            {
                Control ct = this.MainPanel.Controls[i - closeCount];

                if (ct is Form frm)
                {
                    //如果是我们需要打开的窗体，那么就置前
                    if (frm.Text == formName.ToString())
                    {
                        frm.BringToFront();
                        isFind = true;
                        break;
                    }
                    //如果不是我们需要打开的窗体，我们需要判断当前的窗体是不是固定窗体
                    else if ((FormName)Enum.Parse(typeof(FormName), frm.Text) >= FormName.临界窗体)
                    {
                        frm.Close();
                        closeCount++;
                    }
                }
            }
            //如果没有找到
            if (isFind == false)
            {
                Form frm = null;
                switch (formName)
                {
                    case FormName.控制流程:
                        frm = new FrmMonitor();
                        break;
                    case FormName.日志报警:
                        frm = new FrmAlarmLog();

                        //绑定委托
                        CommomMethods.AddLogDelegate = ((FrmAlarmLog)frm).AddLog;
                        CommomMethods.AddOPLogDelegate = ((FrmAlarmLog)frm).AddOPLog;
                        this.AddAlarmDelegate = ((FrmAlarmLog)frm).AddAlarm;
                        break;
                    case FormName.临界窗体:
                        break;
                    case FormName.日志查询:
                        frm = new FrmHistoryLog();
                        break;
                    case FormName.参数设置:
                        frm = new FrmParamSet();
                        break;
                    case FormName.实时趋势:
                        frm = new FrmActualTrend();
                        break;
                    case FormName.历史趋势:
                        frm = new FrmHistoryTrend();
                        break;
                    case FormName.数据报表:
                        frm = new FrmReport();
                        break;
                    case FormName.用户管理:
                        frm = new FrmUserManage();
                        break;
                    default:
                        break;
                }
                if (frm != null)
                {
                    //非置顶控件
                    frm.TopLevel = false;
                    //去边框
                    frm.FormBorderStyle = FormBorderStyle.None;
                    //设置填充
                    frm.Dock = DockStyle.Fill;
                    //设置父容器
                    frm.Parent = this.MainPanel;
                    //置前
                    frm.BringToFront();
                    frm.Show();
                }
            }
        }
        #endregion

        #region 窗体拖动
        public static Point CPoint;

        private void Form_MouseDown(object sender, MouseEventArgs e)
        {
            CPoint = new Point(-e.X, -e.Y);
        }

        private void Form_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                Point myPosittion = Control.MousePosition;//获取当前鼠标的屏幕坐标
                myPosittion.Offset(CPoint.X, CPoint.Y);//重载当前鼠标的位置
                this.DesktopLocation = myPosittion;//设置当前窗体在屏幕上的位置
            }
        }
        #endregion

        #region 退出二次确认
        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult dialogResult = new FrmMessageBoxWithAck("是否确定要退出系统", "退出系统").ShowDialog();
            if (dialogResult == DialogResult.OK)
            {
                //关闭存储定时器
                this.storeTimer.Stop();

                //关闭线程
                CommomMethods.plcDevice?.Cts?.Cancel();
                Thread.Sleep(500);
                Environment.Exit(0);
            }
            else
            {
                e.Cancel = true;
            }

        }
        #endregion

        #region 减少闪烁
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams parss = base.CreateParams;
                parss.ExStyle |= 0x02000000;
                return parss;
            }
        }
        #endregion

        #region 获取星期信息
        private string[] weeks = new string[] { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };
        private string week
        {
            get { return weeks[Convert.ToInt32(DateTime.Now.DayOfWeek)]; }
        }
        #endregion
    }
}
